package com.ttx.single.lab.service.transform;

import com.ttx.single.lab.mapper.OrderItemMapper;
import com.ttx.single.lab.mapper.OrderMapper;
import com.ttx.single.lab.model.bo.OrderBO;
import com.ttx.single.lab.model.dataobject.OrderDO;
import com.ttx.single.lab.model.dataobject.OrderItemDO;
import com.ttx.single.lab.model.dto.PlaceOrderDto;
import com.ttx.single.lab.service.CommonDoubleWriteOrderService;
import com.ttx.single.lab.service.OrderService;
import com.ttx.single.lab.service.defaultimpl.OrderServiceTransformStep1;
import com.ttx.single.lab.util.MockUtil;
import com.ttx.suite.web.model.bo.PageBO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;

/**
 * 2
 * # 1 使用uid的初始下单  2 下单双写，以单库读写为主  3  下单双写， 以分库读写为主 4 下单只写在分库
 * @author TimFruit
 * @date 20-4-12 上午8:58
 */
@Service
public class OrderServiceTransformStep2 implements OrderService {

    //单库
    @Autowired
    @Qualifier("singleOrderMapper")
    OrderMapper singleOrderMapper;
    @Autowired
    @Qualifier("singleOrderItemMapper")
    OrderItemMapper singleOrderItemMapper;


    //分库分表
    @Autowired
    @Qualifier("shardingOrderMapper")
    OrderMapper shardingOrderMapper;
    @Autowired
    @Qualifier("shardingOrderItemMapper")
    OrderItemMapper shardingOrderItemMapper;

    @Autowired
    CommonDoubleWriteOrderService doubleWriteOrderService;
    @Autowired
    OrderServiceTransformStep1 orderServiceTransformStep1;




    @Override
    public void placeOrder(PlaceOrderDto orderDto) {
        //2 下单双写，以单库读写为主
        OrderDO orderDO= doubleWriteOrderService.generateOrderId(orderDto);
        List<OrderItemDO> orderItemDOS= doubleWriteOrderService.generateOrderItemIds(orderDto.getItemDtos(),orderDO.getOrderId());

        //以单库为主, single - sharding

        //单库事务执行成功后， 即时分库事务执行失败
        //通过数据同步 (单库 -> 分库) , 可以将差异补平
        doubleWriteOrderService.singlePlaceOrder(orderDO, orderItemDOS);

        doubleWriteOrderService.shardingPlaceOrder(orderDO, orderItemDOS);





        //模拟异常
        MockUtil.randomException();

        //保存order_id 和 userid的映射关系
        doubleWriteOrderService.insertOrderMapping(orderDO.getOrderId(), orderDO.getUserId());



        //模拟异常
        MockUtil.randomException();
    }



    // --------- 以单库读为主

    @Override
    public PageBO<OrderBO> listUserOrderPage(Long userId, Integer pageNum, Integer pageSize) {
        //单库读
        return orderServiceTransformStep1.listUserOrderPage(userId,pageNum, pageSize);
    }

    @Override
    public OrderBO selectOrder(Long orderId) {
        //单库读
        return orderServiceTransformStep1.selectOrder(orderId);
    }


    //-------双写,以单库读写为主
    @Override
    public void cancelOrder(Long orderId, Integer userId) {
        Date date=new Date();
        doubleWriteOrderService.singleCancelOrder(orderId,userId,date);
        doubleWriteOrderService.shardingCancelOrder(orderId, userId,date);
    }


}
